package com.zuozhj.service.impl;

import com.zuozhj.entity.SysMenu;
import com.zuozhj.entity.SysRole;
import com.zuozhj.entity.SysUser;
import com.zuozhj.mapper.SysUserMapper;
import com.zuozhj.service.ISysMenuService;
import com.zuozhj.service.ISysRoleService;
import com.zuozhj.service.ISysUserService;
import com.zuozhj.utils.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zuozhj
 * @since 2022-12-02
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    ISysRoleService sysRoleService;

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    ISysMenuService sysMenuService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public SysUser getByUsername(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username", username));
    }

    /* 获取用户的角色权限 */
    @Override
    public String getUserAuthorityInfo(Long userId) {
        
        String authority = "";
        
        SysUser sysUser = sysUserMapper.selectById(userId);
        // redisUtil.del("GrantedAuthority:" + sysUser.getUsername());
        // redis 缓存用户的角色权限， 减少数据库查询
        if (redisUtil.hasKey("GrantedAuthority:" + sysUser.getUsername())) {
            authority = (String) redisUtil.get("GrantedAuthority:" + sysUser.getUsername());
        } else {

            List<SysRole> roles = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id = " + userId));

            if (roles.size() > 0) {
                // 获取角色表的code字段， 用","隔开
                String roleCodes = roles.stream().map(role -> "ROLE_" + role.getCode()).collect(Collectors.joining(","));
                authority = roleCodes;
            }
        
            List<Long> menuIds = sysUserMapper.getNavMenuIds(userId);

            if (menuIds.size() > 0) {
                List<SysMenu> menus = sysMenuService.listByIds(menuIds);
                String perms = menus.stream().map(menu -> menu.getPerms()).collect(Collectors.joining(","));

                if (authority != "") {
                    authority = authority.concat(",").concat(perms);
                } else {
                    authority = authority.concat(perms);
                }
                // System.out.println("**********************************************************");
                // System.out.println(authority);
                // System.out.println("**********************************************************");
            }
            
            redisUtil.set("GrantedAuthority:" + sysUser.getUsername(), authority, 3600);
        }

        return authority;
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del("GrantedAuthority:" + username);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        // 用户角色发生改变时 要删除所有用户拥有该角色权限的缓存
        List<SysUser>  sysUsers= this.list(new QueryWrapper<SysUser>().inSql("id", "select user_id from sys_user_role where role_id = " + roleId));

        sysUsers.forEach(user -> {
            this.clearUserAuthorityInfo(user.getUsername());
        });
    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        // 菜单权限发生改变时 要删除所有用户拥有该角色权限的缓存
        
        String sql = "select distinct ur.user_id from sys_user_role ur left join sys_role_menu rm on ur.role_id = rm.role_id where rm.menu_id = " + menuId;
        List<SysUser>  sysUsers= this.list(new QueryWrapper<SysUser>().inSql("id", sql));

        sysUsers.forEach(user -> {
            this.clearUserAuthorityInfo(user.getUsername());
        });
    }

}
